package com.dhcc.DRGsHosp.application.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Named;

import org.dayatang.querychannel.JdbcTemplateObj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;

import com.dhcc.DRGsHosp.application.DrgsIndexCalApplication;
import com.dhcc.DRGsHosp.application.FeeStageApplication;
import com.dhcc.DRGsHosp.core.domain.IndexCal;
import com.dhcc.DRGsHosp.infra.util.StringUtils;

/**
 * @title		:FeeStageApplicationImpl.java
 * @description	:
 * @author		:WangTeng
 * @date		:2015年11月30日
 * @version     :1.0
 * @copyright   :DHCC 2013-2014 
 */
@Named
public class FeeStageApplicationImpl implements FeeStageApplication {
	
	@Autowired
	private JdbcTemplateObj jdbcTemplateObj;
/**
 * 
 *  @Description：获取科室费用分段数据
 *  @Author LiuHongJun  
 *  @see com.dhcc.DRGsHosp.application.FeeStageApplication#getFeeStageData(com.dhcc.DRGsHosp.core.domain.IndexCal)
 */
	@Override
	@Cacheable(value = "drgscom3.1.1", key = "'getFeeStageData' + #index.pType +  "
	+ "#index.dateFrom + #index.dateTo + "
	+ "#index.pardepgroupCode + #index.pardepCode + #index.pargroupName + #index.protomedicus + "
	+ "#index.parwardCode  + "
	+ "#index.resident + #index.parmdcCode + #index.paradrgCode + #index.pardrgCode +"
	+ "#index.verCode + #index.type1+ #index.hospCode+ #verRegion")
	public List<Map<String, Object>> getFeeStageData(IndexCal index,String verRegion) {
		String dateFrom = index.getDateFrom();
		String dateTo = index.getDateTo();
		String depgroupCode = index.getPardepgroupCode();
		String pType = index.getpType();
		String depCode = index.getPardepCode();
		String groupName = index.getPargroupName();
		String drgCode = index.getPardrgCode();
		String specialDep=index.getType1();//特殊部门
		String hospCode=index.getHospCode();
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT DEPCATE ,ORDER_DOC_DEP STAGEDEP,ROUND(STAGEFEE/10000,2) STAGEFEE, \n");//分段科室、描述、分段费用
		sql.append("ROUND(100*STAGEFEE/SUM(STAGEFEE)OVER(PARTITION BY 1),2) STAGERATIO,ROUND(STAGEFEE/TOTALCASECNT,2) AVGFEE,    \n");//分段费用占比
		sql.append("ROUND(MATERIALFEE/10000,2) MATERIALFEE,ROUND(100*MATERIALFEE/STAGEFEE,2) MATERIALRATIO,  \n");//耗占比
		sql.append("ROUND(DRUGFEE/10000,2) DRUGFEE,ROUND(100*DRUGFEE/STAGEFEE,2) DRUGRATIO,  \n");//药占比
		sql.append("TOTALCASECNT,ORDERQUANTITY FROM ( \n");//病例数、医嘱项数量
		if(StringUtils.hasLength(specialDep)){
			sql.append("SELECT DEPCATE,CASE WHEN DEPCATE='OTHER' THEN '其他' \n");//分段科室与描述，如果有特殊部门，则分为当前查询科室、特殊部门、其他三类
			sql.append("ELSE ORDER_DOC_DEP END ORDER_DOC_DEP, \n");
		}
		else{//没有配置特殊部门时，查询分段费用前五的特殊部门
			sql.append("SELECT DEPCATE,ORDER_DOC_DEP,SUM(STAGEFEE) STAGEFEE,\n");
			sql.append("SUM(MATERIALFEE) MATERIALFEE,SUM(DRUGFEE) DRUGFEE, SUM(TOTALCASECNT) TOTALCASECNT,SUM(ORDERQUANTITY) ORDERQUANTITY FROM(\n");
			sql.append("SELECT CASE WHEN ROWNUM>5 THEN 'OTHER' ELSE DEPCATE END DEPCATE,\n");
			sql.append("CASE WHEN ROWNUM>5 THEN '其他' ELSE ORDER_DOC_DEP END ORDER_DOC_DEP,\n");
			sql.append("STAGEFEE,MATERIALFEE,DRUGFEE,TOTALCASECNT,ORDERQUANTITY from (\n");
			sql.append("SELECT DEPCATE,ORDER_DOC_DEP, \n");
		}
		sql.append("SUM(ORDER_TOTAL_FEE) STAGEFEE, \n");//分段费用
		sql.append("SUM(CASE WHEN PARCOST_CATE_CODE=1 THEN ORDER_TOTAL_FEE ELSE 0 END) MATERIALFEE, \n");//材料费
		sql.append("SUM(CASE WHEN PARCOST_CATE_CODE=2 THEN ORDER_TOTAL_FEE ELSE 0 END) DRUGFEE, \n");//药品费用
		sql.append("COUNT(DISTINCT PMAININDEX) TOTALCASECNT,  \n");//病例数
		sql.append("COUNT(DISTINCT ORDER_ID||ORDER_DESC) ORDERQUANTITY from ( \n");//医嘱项数量
		
		sql.append("SELECT MRIP.PMAININDEX,ORDER_ID,ORDER_DESC,ORDER_TOTAL_FEE,COSTSUB.PARCOST_CATE_CODE,ORDER_DOC_DEP,ORDER_DOC_DEP_CODE,DEP.DEP_NAME,\n");
		if(StringUtils.hasLength(specialDep)){
			String depArray[]=specialDep.split(",");
			sql.append("CASE  \n");
			for(int i=0;i<depArray.length;i++){
				sql.append("WHEN ORDER_DOC_DEP="+depArray[i]+" THEN "+depArray[i]+"  \n");
			}
			sql.append("ELSE 'OTHER' END AS DEPCATE \n");
		}
		else{
			sql.append("ORDER_DOC_DEP AS DEPCATE \n");
		}
		sql.append("FROM DRGS.MR_IPINFO MRIP   \n");
		sql.append("LEFT JOIN DRGS.T_PATIENTDRG PDG ON MRIP.PMAININDEX=PDG.PARID  AND PDG.VER_REGION='"+verRegion+"' ");
		sql.append("LEFT JOIN DRGS.MR_BASEINFO MRBS ON MRBS.PMAININDEX=MRIP.PMAININDEX  \n");
		sql.append("LEFT JOIN DRGS.T_DEPARTMENT DEP ON MRIP.P00300001=DEP.DEP_CODE \n ");
		sql.append("LEFT JOIN DRGS.T_DEPGROUP DEPGROUP ON DEPGROUP.DEPGROUP_CODE=DEP.PARDEPGROUP_CODE  \n");
		sql.append("LEFT JOIN DRGS.T_ORDER_RANGE_MONTH ORDERMONTH ON MRBS.P00220400 = ORDERMONTH.ORDER_MR_ID \n");
		sql.append("LEFT JOIN DRGS.T_COSTSUB COSTSUB ON COSTSUB.ORDER_SCODE=ORDERMONTH.ORDER_FIRSTPAGE_FEE \n");
		
		sql.append("WHERE 1=1 \n");
		sql.append("AND INSTR('"+hospCode+"',MRBS.P00010001)>0  \n");
		if (StringUtils.hasLength(depgroupCode)) {
			sql.append("AND DEPGROUP.DEPGROUP_CODE='"+depgroupCode+"' \n");
		}
		if (StringUtils.hasLength(depCode)) {
			sql.append("AND MRIP.P00300001='"+depCode+"' \n");
		}
		if (StringUtils.hasLength(groupName)) {
			sql.append("AND MRIP.P00601001 = '"+ groupName +"'");
		}
		if (StringUtils.hasLength(drgCode)) {
			if("未入组".equals(drgCode)){
				sql.append(" AND PDG.PARDRG_CODE IS NULL \n");
			}
			else{
				sql.append(" AND PDG.PARDRG_CODE='"+drgCode+"' \n");
			}
		}
		if ("1".equals(pType)){
			sql.append(" AND ORDERMONTH.ISMEDINS=1 \n");
		}
		if (StringUtils.hasLength(dateFrom)&&StringUtils.hasLength(dateTo)) {
			sql.append(" AND ORDERMONTH.OUT_DATE BETWEEN TO_DATE('"+dateFrom+"','yyyy-mm-dd') AND TO_DATE('"+dateTo+"','yyyy-mm-dd') \n");
		}
		sql.append(") \n");
		if(StringUtils.hasLength(specialDep)){
			sql.append("GROUP BY DEPCATE,CASE WHEN DEPCATE='OTHER' THEN '其他' \n");
			sql.append("ELSE ORDER_DOC_DEP END) \n");
		}
		else{
			sql.append("GROUP BY DEPCATE,ORDER_DOC_DEP ORDER BY STAGEFEE DESC)) \n");
			sql.append("GROUP BY DEPCATE,ORDER_DOC_DEP) \n");
		}
		
		System.err.println(sql.toString());
		List<Map<String, Object>> resultList = jdbcTemplateObj.queryForList(sql.toString());
		if(!StringUtils.hasLength(specialDep)&&resultList.size()>5){//没有配置特殊部门时，上述sql计算的其他特殊部门的病例数和医嘱项数不对，需另外计算
			resultList=getOtherFeeStageData(index,verRegion,resultList);
		}
		return resultList;
	}
	
	@Cacheable(value = "drgscom3.1.1", key = "'getOtherFeeStageData' + #index.pType +  "
			+ "#index.dateFrom + #index.dateTo + "
			+ "#index.pardepgroupCode + #index.pardepCode + #index.pargroupName + #index.protomedicus + "
			+ "#index.parwardCode  + "
			+ "#index.resident + #index.parmdcCode + #index.paradrgCode + #index.pardrgCode +"
			+ "#index.verCode + #index.hospCode+ #verRegion")
	private List<Map<String, Object>> getOtherFeeStageData(IndexCal index,String verRegion,List<Map<String, Object>> list){
		String dateFrom = index.getDateFrom();
		String dateTo = index.getDateTo();
		String depgroupCode = index.getPardepgroupCode();
		String pType = index.getpType();
		String depCode = index.getPardepCode();
		String groupName = index.getPargroupName();
		String drgCode = index.getPardrgCode();
		String hospCode=index.getHospCode();
		StringBuilder sql = new StringBuilder();
		List<Map<String, Object>> resultList=new ArrayList<>();
		List<String> stageDepList=new ArrayList<>();
		Map<String, Object> otherStageMap=new HashMap<>();
		for(Map<String, Object> temp:list){
			if(!"OTHER".equals(temp.get("DEPCATE"))){
				resultList.add(temp);
				stageDepList.add("'"+temp.get("DEPCATE")+"'");
			}
			else{
				otherStageMap=temp;
			}
		}
		sql.append("SELECT ROUND(STAGEFEE/TOTALCASECNT,2) AVGFEE, TOTALCASECNT,ORDERQUANTITY FROM ( \n");//次均费用、病例数、医嘱项数量
		sql.append("SELECT SUM(ORDER_TOTAL_FEE) STAGEFEE, COUNT(DISTINCT PMAININDEX) TOTALCASECNT,  \n");//分段费用、病例数
		sql.append("COUNT(DISTINCT ORDER_ID||ORDER_DESC) ORDERQUANTITY from ( \n");//医嘱项数量
		sql.append("SELECT MRIP.PMAININDEX,ORDER_ID,ORDER_DESC,ORDER_TOTAL_FEE \n");
		sql.append("FROM DRGS.MR_IPINFO MRIP   \n");
		sql.append("LEFT JOIN DRGS.T_PATIENTDRG PDG ON MRIP.PMAININDEX=PDG.PARID  AND PDG.VER_REGION='"+verRegion+"' ");
		sql.append("LEFT JOIN DRGS.MR_BASEINFO MRBS ON MRBS.PMAININDEX=MRIP.PMAININDEX  \n");
		sql.append("LEFT JOIN DRGS.T_DEPARTMENT DEP ON MRIP.P00300001=DEP.DEP_CODE \n ");
		sql.append("LEFT JOIN DRGS.T_DEPGROUP DEPGROUP ON DEPGROUP.DEPGROUP_CODE=DEP.PARDEPGROUP_CODE  \n");
		sql.append("LEFT JOIN DRGS.T_ORDER_RANGE_MONTH ORDERMONTH ON MRBS.P00220400 = ORDERMONTH.ORDER_MR_ID \n");
		sql.append("LEFT JOIN DRGS.T_COSTSUB COSTSUB ON COSTSUB.ORDER_SCODE=ORDERMONTH.ORDER_FIRSTPAGE_FEE \n");
		
		sql.append("WHERE 1=1 \n");
		sql.append("AND INSTR('"+hospCode+"',MRBS.P00010001)>0  \n");
		sql.append("AND (ORDERMONTH.ORDER_DOC_DEP IS NULL OR ORDERMONTH.ORDER_DOC_DEP NOT IN("+String.join(",", stageDepList)+") ) \n");
		if (StringUtils.hasLength(depgroupCode)) {
			sql.append("AND DEPGROUP.DEPGROUP_CODE='"+depgroupCode+"' \n");
		}
		if (StringUtils.hasLength(depCode)) {
			sql.append("AND MRIP.P00300001='"+depCode+"' \n");
		}
		if (StringUtils.hasLength(groupName)) {
			sql.append("AND MRIP.P00601001 = '"+ groupName +"'");
		}
		if (StringUtils.hasLength(drgCode)) {
			if("未入组".equals(drgCode)){
				sql.append(" AND PDG.PARDRG_CODE IS NULL \n");
			}
			else{
				sql.append(" AND PDG.PARDRG_CODE='"+drgCode+"' \n");
			}
		}
		if ("1".equals(pType)){
			sql.append(" AND ORDERMONTH.ISMEDINS=1 \n");
		}
		if (StringUtils.hasLength(dateFrom)&&StringUtils.hasLength(dateTo)) {
			sql.append(" AND ORDERMONTH.OUT_DATE BETWEEN TO_DATE('"+dateFrom+"','yyyy-mm-dd') AND TO_DATE('"+dateTo+"','yyyy-mm-dd') \n");
		}
		sql.append(") \n");
		sql.append("GROUP BY 1) \n");
		System.err.println(sql.toString());
		List<Map<String, Object>> tempList=jdbcTemplateObj.queryForList(sql.toString());
		if(!otherStageMap.isEmpty()&&!tempList.isEmpty()){
			otherStageMap.put("TOTALCASECNT", tempList.get(0).get("TOTALCASECNT"));
			otherStageMap.put("ORDERQUANTITY", tempList.get(0).get("ORDERQUANTITY"));
			otherStageMap.put("AVGFEE", tempList.get(0).get("AVGFEE"));
			resultList.add(otherStageMap);
		}
		return resultList;
	}
	@Override
	@Cacheable(value = "drgscom3.1.1", key = "'getOrderData' + #index.pType +  "
			+ "#index.dateFrom + #index.dateTo + "
			+ "#index.pardepgroupCode + #index.pardepCode + #index.pargroupName + "
			+ "#index.pardrgCode +"
			+ "#index.type1+ #verRegion")
	public List<Map<String, Object>> getOrderData(IndexCal index,String verRegion) {

		String dateFrom = index.getDateFrom();
		String dateTo = index.getDateTo();
		String depgroupCode = index.getPardepgroupCode();
		String depCode = index.getPardepCode();
		String groupName = index.getPargroupName();
		String drgCode = index.getPardrgCode();
		String pType = index.getpType();
		String stageDep = index.getType1();
		String hospCode=index.getHospCode();
		StringBuilder sql = new StringBuilder();
		sql.append(" SELECT  \n ");
		sql.append(" ORDERMONTH.ORDER_ID ORDERID, ORDERMONTH.ORDER_DESC ORDERDESC, \n ");
		sql.append(" SUM (ORDERMONTH.ORDER_TOTAL_FEE) AS OrderTotalFee, \n ");
		sql.append(" ROUND( SUM (ORDERMONTH.ORDER_TOTAL_FEE)*100/SUM(ORDERMONTH.COSTAMOUNT) ,2) AS ORDERFEERATIO, \n ");
		sql.append(" ROUND( SUM (ORDERMONTH.ORDER_TOTAL_FEE)/COUNT (DISTINCT ORDERMONTH.ORDER_MR_ID) ,2) AS AVGORDERFEE, \n ");
		sql.append(" COUNT (DISTINCT ORDERMONTH.ORDER_MR_ID) AS CASECNT, \n ");
		sql.append(" SUM (ORDERMONTH.ORDER_QUANTITY) AS ORDERQUANTITY, \n ");
		sql.append(" MAX (ORDERMONTH.ORDER_UNIT_PRICE) AS ORDERUNITPRICE \n ");
		sql.append("FROM DRGS.MR_IPINFO MRIP   \n");
		sql.append("LEFT JOIN DRGS.T_PATIENTDRG PDG ON MRIP.PMAININDEX=PDG.PARID  AND PDG.VER_REGION='"+verRegion+"' ");
		sql.append("LEFT JOIN DRGS.MR_BASEINFO MRBS ON MRBS.PMAININDEX=MRIP.PMAININDEX  \n");
		sql.append("LEFT JOIN DRGS.T_DEPARTMENT DEP ON MRIP.P00300001=DEP.DEP_CODE \n ");
		sql.append("LEFT JOIN DRGS.T_DEPGROUP DEPGROUP ON DEPGROUP.DEPGROUP_CODE=DEP.PARDEPGROUP_CODE  \n");
		sql.append("LEFT JOIN DRGS.T_ORDER_RANGE_MONTH ORDERMONTH ON MRBS.P00220400 = ORDERMONTH.ORDER_MR_ID \n");
		sql.append("LEFT JOIN DRGS.T_COSTSUB COSTSUB ON COSTSUB.ORDER_SCODE=ORDERMONTH.ORDER_FIRSTPAGE_FEE \n");
		sql.append(" WHERE 1=1 \n ");
		sql.append("AND INSTR('"+hospCode+"',MRBS.P00010001)>0  \n");
		if (StringUtils.hasLength(depgroupCode)) {
			sql.append("AND DEPGROUP.DEPGROUP_CODE='"+depgroupCode+"' \n");
		}
		if (StringUtils.hasLength(depCode)) {
			sql.append("AND MRIP.P00300001='"+depCode+"' \n");
		}
		if (StringUtils.hasLength(groupName)) {
			sql.append("AND MRIP.P00601001 = '"+ groupName +"'");
		}
		if (StringUtils.hasLength(drgCode)) {
			if("未入组".equals(drgCode)){
				sql.append(" AND PDG.PARDRG_CODE IS NULL \n");
			}
			else{
				sql.append(" AND PDG.PARDRG_CODE='"+drgCode+"' \n");
			}
		}
		if ("1".equals(pType)){
			sql.append(" AND ORDERMONTH.ISMEDINS=1 \n");
		}
		if (StringUtils.hasLength(stageDep)){
			if(stageDep.contains(",")){
				sql.append(" AND (ORDERMONTH.ORDER_DOC_DEP IS NULL OR ORDERMONTH.ORDER_DOC_DEP NOT IN("+stageDep+") )\n");
			}
			else{
				sql.append(" AND ORDERMONTH.ORDER_DOC_DEP='"+stageDep+"' \n");
			}
		}
		if (StringUtils.hasLength(dateFrom)&&StringUtils.hasLength(dateTo)) {
			sql.append(" AND ORDERMONTH.OUT_DATE BETWEEN TO_DATE('"+dateFrom+"','yyyy-mm-dd') AND TO_DATE('"+dateTo+"','yyyy-mm-dd') \n");
		}
		sql.append(" GROUP BY ORDERMONTH.ORDER_ID, ORDERMONTH.ORDER_DESC \n ");
		System.err.println(sql.toString());
		List<Map<String, Object>> resultList = jdbcTemplateObj.queryForList(sql.toString());
		return resultList;
	
	}
	/**
	 * 
	 *  @Description：获取医嘱开单科室特殊部门
	 *  @Author WENYI  
	 *  @see com.dhcc.DRGsHosp.application.FeeStageApplication#getOrderSpecialDep()
	 */
	@Override
	public Object getOrderSpecialDep() {
		String sql="SELECT ORDER_DOC_DEP_CODE DEPCODE,ORDER_DOC_DEP DEPDESC FROM DRGS.T_ORDER_DEP WHERE IS_SPECIAL_DEP='1'";
		return jdbcTemplateObj.queryForList(sql);
	}
	
	
}
